
package com.jf.cloud.user.controller.app;

import cn.hutool.core.util.StrUtil;
import com.jf.cloud.api.auth.bo.UserInfoInTokenBO;
import com.jf.cloud.api.biz.feign.NotifyFeignClient;
import com.jf.cloud.api.coupon.feign.CouponFeignClient;
import com.jf.cloud.api.order.feign.OrderFeignClient;
import com.jf.cloud.api.product.feign.SpuFeignClient;
import com.jf.cloud.api.user.vo.UserApiVO;
import com.jf.cloud.common.cache.util.RedisUtil;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.order.vo.OrderCountVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.common.util.Arith;
import com.jf.cloud.user.constant.LevelTypeEnum;
import com.jf.cloud.user.dto.CheckSmsDTO;
import com.jf.cloud.user.dto.UserDTO;
import com.jf.cloud.user.model.User;
import com.jf.cloud.user.model.UserExtension;
import com.jf.cloud.user.service.UserExtensionService;
import com.jf.cloud.user.service.UserLevelService;
import com.jf.cloud.user.service.UserService;
import com.jf.cloud.user.vo.UserInfoVO;
import com.jf.cloud.user.vo.UserLevelVO;
import com.jf.cloud.user.vo.UserSimpleInfoVO;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.util.Objects;

/**
 * 用户地址
 *
 * @author zz
 * @date 2020-12-07 15:50:02
 */
@RestController("appUserController")
@RequestMapping("/user")
@Tag(name = "app-用户信息")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private UserExtensionService userExtensionService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private CouponFeignClient couponFeignClient;

    @Autowired
    private UserLevelService userLevelService;

    @Autowired
    private SpuFeignClient spuFeignClient;
    @Autowired
    private OrderFeignClient orderFeignClient;

    @Autowired
    private NotifyFeignClient notifyFeignClient;

    public static final String UPDATE_PWD_SMS_FLAG = "updatePwdSmsFlag";

    @GetMapping("/simple_info")
    @Operation(summary = "用户头像昵称" , description = "用户头像昵称")
    public ServerResponseEntity<UserSimpleInfoVO> getByAddrId() {
        Long userId = AuthUserContext.get().getUserId();

        UserApiVO userApiVO = userService.getByUserId(userId);
        UserSimpleInfoVO userSimpleInfoVO = new UserSimpleInfoVO();
        userSimpleInfoVO.setNickName(userApiVO.getNickName());
        userSimpleInfoVO.setPic(userApiVO.getPic());

        return ServerResponseEntity.success(userSimpleInfoVO);
    }

    @GetMapping("/user_info")
    @Operation(summary = "获取用户信息" , description = "返回用户的信息")
    public ServerResponseEntity<UserInfoVO> getUserInfo() {
        Long userId = AuthUserContext.get().getUserId();
        UserExtension userExtension = userExtensionService.getByUserId(userId);
        UserInfoVO userInfo = new UserInfoVO();
        userInfo.setScore(userExtension.getScore());
        userInfo.setActualBalance(userExtension.getActualBalance());
        userInfo.setBalance(userExtension.getBalance());
        ServerResponseEntity<Integer> countCanUseCouponResponse = couponFeignClient.countCanUseCoupon();
        userInfo.setCouponNum(countCanUseCouponResponse.getData());
        Integer collections = spuFeignClient.countByUserId(userId).getData();
        userInfo.setCollections(collections == null? 0 :collections);
        // todo 计算未读消息数量
        Integer num = notifyFeignClient.getUnreadMsg(userId).getData();
        userInfo.setNotifyNum(num == null? 0 :num);
        return ServerResponseEntity.success(userInfo);
    }

    @GetMapping("/ma/user_detail_info")
    @Operation(summary = "获取用户详细信息" , description = "返回用户详细信息")
    public ServerResponseEntity<UserApiVO> getUserDetailInfo() {
        UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get();
        if (userInfoInTokenBO == null) {
            return ServerResponseEntity.fail(ResponseEnum.CLEAN_TOKEN);
        }
        Long userId = userInfoInTokenBO.getUserId();
        UserApiVO userApiVO = userService.getByUserId(userId);
        // 会员信息
        UserLevelVO ordinaryLevel = userLevelService.getOneByTypeAndLevel(LevelTypeEnum.ORDINARY_USER.value(), userApiVO.getLevel());
        if (Objects.nonNull(userApiVO.getVipLevel())){
            UserLevelVO payLevel = userLevelService.getOneByTypeAndLevel(LevelTypeEnum.PAY_USER.value(), userApiVO.getVipLevel());
            userApiVO.setVipUserLevelId(payLevel.getUserLevelId());
            userApiVO.setVipLevelName(payLevel.getLevelName());
        }
        if (Objects.nonNull(ordinaryLevel)){
            userApiVO.setUserLevelId(ordinaryLevel.getUserLevelId());
            userApiVO.setLevelName(ordinaryLevel.getLevelName());
        }
        userApiVO.setUserMobile(userApiVO.getPhone());
        return ServerResponseEntity.success(userApiVO);
    }

    @PutMapping("/set_user_info")
    @Operation(summary = "设置用户信息" , description = "设置用户信息")
    public ServerResponseEntity<Void> setUserInfo(@RequestBody UserDTO userDTO) {
        Long userId = AuthUserContext.get().getUserId();
        userDTO.setUserId(userId);
        User user = mapperFacade.map(userDTO, User.class);
        userService.update(user);
        return ServerResponseEntity.success();
    }


    @PutMapping("/update_mobile")
    @Operation(summary = "修改用户手机号" , description = "修改用户手机号")
    public ServerResponseEntity<String> checkPhoneIsBind(@RequestBody CheckSmsDTO checkSmsDTO) {
        //修改手机号码前后不能相同
        Long userId = AuthUserContext.get().getUserId();
        UserApiVO user = userService.getByUserId(userId);
        if (user.getPhone().equals(checkSmsDTO.getMobile())) {
            throw new LuckException("修改手机号码不能与原先相同");
        }
        String checkRegisterSmsFlag = UPDATE_PWD_SMS_FLAG + checkSmsDTO.getCheckUpdatePhoneSmsFlag();
        // 看看有没有校验验证码成功的标识
        if (StrUtil.isBlank(checkSmsDTO.getCheckUpdatePhoneSmsFlag())) {
            // 验证码已过期，请重新发送验证码校验
            throw new LuckException("验证码已过期，请重新发送验证码校验");
        } else {
            String checkRegisterSmsFlagMobile = RedisUtil.get(checkRegisterSmsFlag);
            if (!Objects.equals(checkRegisterSmsFlagMobile, checkSmsDTO.getMobile())) {
                // 验证码已过期，请重新发送验证码校验
                throw new LuckException("验证码已过期，请重新发送验证码校验");
            }
        }
        // 修改用户的手机号
        userService.updateUserMobile(AuthUserContext.get().getUserId(), checkSmsDTO.getMobile());
        return ServerResponseEntity.success();
    }
    @GetMapping ("/destroy_user")
    @Operation(summary = "注销账户" , description = "注销账户")
    public ServerResponseEntity<Void> destroy(@RequestParam(value = "forceDestroy", required = false, defaultValue = "false") Boolean forceDestroy) {
        Long userId = AuthUserContext.get().getUserId();
        // 检查此账户是否有未完成的订单
        ServerResponseEntity<OrderCountVO> orderCountResponseEntity = orderFeignClient.countOrderByUserId(userId);
        if (orderCountResponseEntity.isFail()) {
            throw new LuckException(orderCountResponseEntity.getMsg());
        }
        OrderCountVO orderCountVO = orderCountResponseEntity.getData();
        if (orderCountVO.getConsignment()  + orderCountVO.getPayed() + orderCountVO.getRefund() + orderCountVO.getGrouping() + orderCountVO.getPreSale() > 0) {
            return ServerResponseEntity.fail(ResponseEnum.DESTROY_USER_FAIL);
        }
        if (!forceDestroy) {
            // 检查余额
            UserExtension userExtension = userExtensionService.getByUserId(userId);
            double balance = Arith.div(new Double(userExtension.getActualBalance()), 100L);
            if (balance > 0) {
                String actualBalance = DecimalFormat.getInstance().format(balance).replaceAll(",", "");
                return ServerResponseEntity.showFailMsg("您的账户当前仍有余额" + actualBalance +"元，注销账户后余额将清零，请考虑清楚后再注销");
            }
        }
        userService.destroyUser(userId);
        return ServerResponseEntity.success();
    }

}
